package com.dailywork.basepro.thread.executors;

import com.common.constants.NumberConstants;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 自定义线程池(使用无界队列)
 *
 * @author think
 * @version 1.0.0
 * @since 2020/4/25
 */
@Slf4j
public class UseThreadPoolExecutor2 implements Runnable {

    private static AtomicInteger count = new AtomicInteger(0);
    private static AtomicInteger threadCount = new AtomicInteger(0);

    @Override
    public void run() {
        try {
            int temp = count.incrementAndGet();
            System.out.println("Cur thread name is: " + Thread.currentThread().getName() + "任务" + temp);
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            log.error(e.getMessage(), e);
        }
    }

    /**
     * 无界的任务队列时: LinkedBlockingQueue, 与有界的任务队列相比,除非系统资源耗尽,否则无界的任务队列不存在任务入队失败的情况.
     * 当有新任务到来时,系统的线程数小于CorePoolSize时,则新建线程执行任务,
     * 当达到CorePoolSize后.就不会继续增加,若后续仍有新的任务加入,而又没有空闲的线程资源,则任务直接进入队列等待.
     * 当任务的创建和处理的速度差异很大,无界队列会保持快速增长,直到耗尽系统内存
     */
    public static void main(String[] args) throws Exception {
        BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>(NumberConstants.TEN);
        ExecutorService executor =
                new ThreadPoolExecutor(
                        5,
                        10,
                        120L,
                        TimeUnit.SECONDS,
                        queue, r -> new Thread(r, "My-thread" + threadCount.getAndIncrement()));

        for (int i = 0; i < NumberConstants.TWENTY; i++) {
            executor.submit(new UseThreadPoolExecutor2());
        }
        Thread.sleep(1000);
        System.out.println("queue Size:" + queue.size());
        Thread.sleep(2000);
    }
}
